package com.hollowlatte.manage.shiro;

import com.hollowlatte.common.exceptionhandler.CustomException;
import com.hollowlatte.manage.entity.Perms;
import com.hollowlatte.manage.entity.Role;
import com.hollowlatte.manage.entity.User;
import com.hollowlatte.manage.service.RoleService;
import com.hollowlatte.manage.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @author Hollow Latte
 * @date 2021/5/9 0:08
 */
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取身份信息
        Long userId = (Long) principalCollection.getPrimaryPrincipal();
        List<Role> roleList = userService.listRoleById(userId);

        // 根据数据库给用户授权
        if (CollectionUtils.isEmpty(roleList)) {
            throw new CustomException("A0300 ", "用户无任何权限");
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        roleList.forEach(role -> {
            simpleAuthorizationInfo.addRole(role.getName());
            List<Perms> permsList = roleService.listPermsById(role.getId());
            if (!CollectionUtils.isEmpty(permsList)) {
                permsList.forEach(perms -> simpleAuthorizationInfo.addStringPermission(perms.getName()));
            }
        });
        return simpleAuthorizationInfo;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException, CustomException {
        User user = userService.getById(Long.parseLong((String) authenticationToken.getPrincipal()));
        if (ObjectUtils.isEmpty(user)) {
            throw new UnknownAccountException();
        }

        return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());
    }
}
